package ai;

import game.Game;

public class AlphaBeta extends Minmax {
	
	public AlphaBeta(Game game, byte side)
	{
		super(game, side);
	}
	
	protected int getZet()
	{
		//Copy a new playing field to the ai-array.
		copyPlayingField( this.game.getPlayingField() );
		
		//Set the counter to zero
		this.counter = 0;
		
		//Call the chooseMove function which tries to select an optiomal move
		Reply reply;
		if (this.side == Game.PLAYER1) {
			reply = chooseMove( Game.PLAYER1, Game.PLAYER2_WIN, Game.PLAYER1_WIN, 0, 6);
		}
		else {
			reply = chooseMove( Game.PLAYER2, Game.PLAYER1_WIN, Game.PLAYER2_WIN, 0, 6);
		}
		
		return reply.bestmove;
	}
	

	
	//Alpha Beta Pruning
	private Reply chooseMove( byte side, int alpha, int beta, int depth, int amount)
	{
		byte opponent;
		int value, bestmove = 0;
		Reply reply;
		
		//Increment the counter
		this.counter++;
		
		//Base case
		if (this.game.checkFourOnRow(this.aiPlayingField) != Game.UNCLEAR || amount < 1)
		{
			return new Reply(this.game.checkFourOnRow(this.aiPlayingField));
		}
		
		
		//Assign values depending on which side we are currently on
		if (side == Game.PLAYER1)
		{
			opponent = Game.PLAYER2;
			value = alpha;
		}
		else
		{
			opponent = Game.PLAYER1;
			value = beta;
		}
		
		
		//Select a default move (the first not full column from the left)
		for (int i = 0; i < Game.XSIZE; i++)
		{
			if ( ! this.columnIsFull(i) )
			{
				bestmove = i;
				break;
			}
		}
		
		//Main loop (for each column)
		Outer:
		for (int i = 0; i < Game.XSIZE; i++)
		{
			if ( ! this.columnIsFull(i) )
			{
				//Insert a token in the current column
				placeToken(i ,side);
				
				//Calling the function recursive
				reply = chooseMove(opponent, alpha, beta, depth+1, amount-1);
				
				//Remove the token again
				removeToken(i);
				
				//Update the return values if we've found a better move
				if ((side == Game.PLAYER1 && reply.value < value) ||
						(side == Game.PLAYER2 && reply.value > value))
				{
					if( side == this.side)
						alpha = value = reply.value;
					else
						beta = value = reply.value;
					
					value = reply.value;
					bestmove = i;
					
					//Checking if it's a refutation, if so then skip node
					if ( alpha >= beta)
						break Outer; // Refutation
				}
			}
		}
		return new Reply(value, bestmove);
	}
	
	
}